#ifndef OLSFITTER_H
#define OLSFITTER_H

#include <abstractfitter.h>
#include <functional>

class OLSFitter : public AbstractFitter {
public:
    OLSFitter();

    //设置拟合所用的公式
    //y = f(x) --> processY(y) = a0*g0(x) + a1*g1(x) + ... +an*gn(x)
    //y = eval(processY(y)) = eval(a0*g0(x) + a1*g1(x) + ... +an*gn(x))
    //g代表基函数,a为需要求解的系数
    bool setFormulas(const std::vector<std::function<double(double)>> &g,
                     const std::function<double(double)> &processY, const std::function<double(double)> &eval);

    //设置拟合所需的数据点
    bool setPoints(const Vecd &x, const Vecd &y) override;

    //根据拟合的公式计算f(x)
    double operator()(double x) override;

    //进行最小二乘拟合
    void calcCoefficients();

    //设置拟合所用的公式为y = a*exp(bx)
    void setExp();

    //设置拟合所用的公式为y = a0+a1*x + a2*x^2 + ... +an*x^n
    void setPoly(int n = 1);

private:
    //基函数
    std::vector<std::function<double(double)>> m_g;
    std::function<double(double)> m_eval;
    std::function<double(double)> m_processY;
    //系数
    Arrd m_a;
};

#endif // OLSFITTER_H
